<script setup lang="ts">
import {onBeforeMount, ref, watch} from 'vue'
import {NButton, NInput} from 'naive-ui'
import {StIconIconify} from 'st-common-ui-vue3'
import 'st-common-ui-vue3/es/components/StIconIconify/StIconIconify.css'
import Plus from '@iconify-icons/tabler/plus'
import Minus from '@iconify-icons/tabler/minus'
import {isStr} from 'st-common-core'
import {StnListInputProps} from './type.ts'

/**
 * 组件配置选项
 */
defineOptions({
  name: 'StnListInput',
})

/**
 * 组件参数
 */
const {
  subListLen = 1,
  placeholder = '请输入',
  inputProps = {},
  emptyButtonProps = {},
  addButtonProps = {},
  removeButtonProps = {},
} = defineProps<StnListInputProps>()

/**
 * 组件双向绑定数据
 */
const value = defineModel<Array<Array<any>>>('value', {default: []})

// 列表数据
const list = ref<Array<{ id: number, subList: Array<any> }>>([])
// 预处理列表数据
onBeforeMount(() => {
  for (const subList of value.value) {
    list.value.push({id: Date.now(), subList: subList})
  }
})
// 监听列表长度的变化，更新 value
watch(() => list.value.length, () => {
  // 清空双向绑定的列表中的子列表
  value.value.splice(0, value.value.length)
  // 将新的子列表添加到双向绑定的列表中
  for (let i = 0; i < list.value.length; i++) {
    const subList = list.value[i].subList
    for (let j = 0; j < subListLen; j++) {
      if (subList[j] === undefined) subList[j] = null
    }
    value.value.push(subList)
  }
})
/**
 * 列表数据中添加子列表项
 *
 * @param {number} index 要在列表中哪个位置添加
 */
const addSubListHandler = (index: number = 0) => {
  list.value.splice(index, 0, {id: Date.now(), subList: []})
}
/**
 * 删除指定索引位置上的子列表项
 *
 * @param {number} index 要删除的子列表项在列表中的索引
 */
const delSubListHandler = (index: number) => {
  list.value.splice(index, 1)
}
</script>

<template>
  <div class="stn-list-input">
    <div v-if="list.length === 0" class="stn-list-input__empty">
      <slot name="list-empty" :addSubListHandler="addSubListHandler">
        <n-button
          v-bind="{
            type: 'primary',
            block: true,
            dashed: true,
            ...emptyButtonProps,
            onClick: () => addSubListHandler(),
          }"
        >
          <template #icon>
            <StIconIconify :icon="Plus"/>
          </template>
        </n-button>
      </slot>
    </div>
    <div v-else class="stn-list-input__list">
      <div
        v-for="(item, index) in list"
        :key="item.id"
        class="stn-list-input__list__sub-list"
      >
        <div
          class="stn-list-input__list__sub-list-item"
          v-for="i in subListLen"
        >
          <slot
            name="sub-list-item-ipt"
            :subList="item.subList"
            :i="i - 1"
            :value="item.subList[i - 1]"
            @update:value="(newVal: any) => item.subList[i - 1] = newVal"
          >
            <n-input
              v-bind="{
                clearable: true,
                placeholder: isStr(placeholder) ? placeholder : placeholder[i - 1],
                ...(Array.isArray(inputProps) ? inputProps[i - 1] : inputProps),
                value: item.subList[i - 1],
                'onUpdate:value': (newVal: any) => item.subList[i - 1] = newVal,
              }"
            />
          </slot>
        </div>
        <div class="stn-list-input__list__sub-list-add">
          <slot name="sub-list-add" :addSubListHandler="addSubListHandler" :index="index + 1">
            <n-button
              v-bind="{
                type: 'primary',
                dashed: true,
                ...addButtonProps,
                onClick: () => addSubListHandler(index + 1),
              }"
            >
              <template #icon>
                <StIconIconify :icon="Plus"/>
              </template>
            </n-button>
          </slot>
        </div>
        <div class="stn-list-input__list__sub-list-del">
          <slot name="sub-list-del" :delSubListHandler="delSubListHandler" :index="index">
            <n-button
              v-bind="{
                type: 'error',
                dashed: true,
                ...removeButtonProps,
                onClick: () => delSubListHandler(index),
              }"
            >
              <template #icon>
                <StIconIconify :icon="Minus"/>
              </template>
            </n-button>
          </slot>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.stn-list-input {
  flex: 1;
  width: 100%;

  .stn-list-input__empty {
    width: 100%;
  }

  .stn-list-input__list {
    width: 100%;

    .stn-list-input__list__sub-list {
      width: 100%;
      display: flex;
      align-items: center;
      gap: 0.5rem;

      &:nth-child(n + 2) {
        margin-top: 0.5rem;
      }

      .stn-list-input__list__sub-list-item {
        flex: 1;
      }
    }
  }
}
</style>
